package starfire.gui;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.table.*;
import java.util.*;

import starfire.task.*;
import starfire.manager.TaskManager;

/**
 * <p>Title: JFtp</p>
 * <p>Description: ftp client</p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: </p>
 * @author starfire
 * @version 1.0
 */

public class DownloadManagerPanel extends JPanel {
  BorderLayout borderLayout1 = new BorderLayout();
  JSplitPane jSplitPane1 = new JSplitPane();
  JScrollPane jScrollPane1 = new JScrollPane();
  JSplitPane jSplitPane2 = new JSplitPane();
  JTree taskTree = new JTree();
  JScrollPane jScrollPane2 = new JScrollPane();
  JSplitPane jSplitPane3 = new JSplitPane();
  JScrollPane jScrollPane3 = new JScrollPane();
  JScrollPane jScrollPane4 = new JScrollPane();
  JTree taskStatusTree = new JTree();
  JList taskDetailStatusList = new JList();
  JTable taskTable = new JTable();
  JPopupMenu taskTreeMenu = new JPopupMenu();
  JPopupMenu taskTableMenu = new JPopupMenu();
  JPopupMenu taskStatusTreeMenu = new JPopupMenu();
  JPopupMenu detailMenu = new JPopupMenu();
  javax.swing.Timer timer = null;

  public static final int statusColumn = 0;
  public static final int resumeColumn = 1;
  public static final int nameColumn = 2;
  public static final int lengthColumn = 3;
  public static final int finishedLengthColumn = 4;
  public static final int percentColumn = 5;
  public static final int usedTimeColumn = 6;
  public static final int leftTimeColumn = 7;
  public static final int currentSpeedColumn = 8;
  public static final int maxSpeedColumn = 9;
  public static final int blockNumColumn = 10;
  public static final int retryNumColumn = 11;
  public static final int urlColumn = 12;
  public static final int commentColumn = 13;

  public static int columnCount = 14;

  public static Object[] strColumnInfo = null;
  public static boolean inited = false;

  public static int[] columnWidths =
  {
      60,60,150,60,60,60,60,60,60,60,60,60,300,150
  };
  JMenuItem startItem = new JMenuItem();
  JMenuItem stopItem = new JMenuItem();
  JMenuItem pauseItem = new JMenuItem();
  JMenuItem restartItem = new JMenuItem();
  JMenuItem deleteItem = new JMenuItem();

  static
  {
    strColumnInfo = new Object[columnCount];
    strColumnInfo[0] = "status";
    strColumnInfo[1] = "resume";
    strColumnInfo[2] = "name";
    strColumnInfo[3] = "length";
    strColumnInfo[4] = "finished";
    strColumnInfo[5] = "percent";
    strColumnInfo[6] = "usedTime";
    strColumnInfo[7] = "leftTime";
    strColumnInfo[8] = "currentSpeed";
    strColumnInfo[9] = "maxSpeed";
    strColumnInfo[10] = "blockNum";
    strColumnInfo[11] = "retry";
    strColumnInfo[12] = "url";
    strColumnInfo[13] = "comment";
    inited = true;
  }


  public DownloadManagerPanel() {
    try {
      jbInit();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
  }
  void jbInit() throws Exception {
    this.setLayout(borderLayout1);
    jSplitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT);
    jScrollPane2.getViewport().setBackground(Color.white);
    jSplitPane3.setDividerSize(5);
    jScrollPane3.getViewport().setBackground(Color.white);
    jScrollPane4.getViewport().setBackground(Color.white);
    jScrollPane1.getViewport().setBackground(Color.white);
    taskTable.setFont(new java.awt.Font("Dialog", 0, 12));
    taskTable.addMouseListener(new DownloadManagerPanel_taskTable_mouseAdapter(this));
    taskTree.setFont(new java.awt.Font("Dialog", 0, 12));
    taskStatusTree.setFont(new java.awt.Font("Dialog", 0, 12));
    taskDetailStatusList.setFont(new java.awt.Font("Dialog", 0, 12));
    startItem.setText("Start");
    stopItem.setText("Stop");
    stopItem.addActionListener(new DownloadManagerPanel_stopItem_actionAdapter(this));
    pauseItem.setText("Pause");
    pauseItem.addActionListener(new DownloadManagerPanel_pauseItem_actionAdapter(this));
    restartItem.setText("Restart");
    restartItem.addActionListener(new DownloadManagerPanel_restartItem_actionAdapter(this));
    deleteItem.setText("Delete");
    deleteItem.addActionListener(new DownloadManagerPanel_deleteItem_actionAdapter(this));
    this.add(jSplitPane1, BorderLayout.CENTER);
    jSplitPane1.add(jScrollPane1, JSplitPane.LEFT);
    jScrollPane1.getViewport().add(taskTree, null);
    jSplitPane1.add(jSplitPane2, JSplitPane.RIGHT);
    jSplitPane2.add(jSplitPane3, JSplitPane.BOTTOM);
    jSplitPane3.add(jScrollPane3, JSplitPane.LEFT);
    jScrollPane3.getViewport().add(taskStatusTree, null);
    jSplitPane3.add(jScrollPane4, JSplitPane.RIGHT);
    jSplitPane2.add(jScrollPane2, JSplitPane.TOP);
    jScrollPane2.getViewport().add(taskTable, null);
    jScrollPane4.getViewport().add(taskDetailStatusList, null);
    taskTableMenu.add(startItem);
    taskTableMenu.add(stopItem);
    taskTableMenu.add(pauseItem);
    taskTableMenu.add(restartItem);
    taskTableMenu.add(deleteItem);
    jSplitPane1.setDividerLocation(100);
    jSplitPane3.setDividerLocation(100);
    jSplitPane2.setDividerLocation(100);
    taskTree.setModel(getTaskTreeModel());
    taskTable.setShowGrid(false);
    taskTable.setModel(new TaskTableModel());
    TableColumnModel columnModel = taskTable.getColumnModel();
    TableColumn[] columns = new TableColumn[columnCount];

    for (int i = 0; i < columnCount; i++) {
        columns[i] = columnModel.getColumn(i);
        columns[i].setPreferredWidth(columnWidths[i]);
        columns[i].setMaxWidth(columnWidths[i]);
        columns[i].setMinWidth(columnWidths[i]);
    }
    taskTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    taskTable.doLayout();

    timer = new javax.swing.Timer(1000,new TimerListener());
    timer.start();
  }

  class TimerListener implements ActionListener
  {
    public void actionPerformed(ActionEvent event)
    {
      taskTable.updateUI();
      DefaultTreeModel model = (DefaultTreeModel)taskTree.getModel();
      DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();
      DefaultMutableTreeNode node = null;
      Task task = null;
      TaskDescription description = null;
      TaskProcess process = null;
      Enumeration enu = null;
      DefaultMutableTreeNode curNodes = (DefaultMutableTreeNode)root.getChildAt(0);
      DefaultMutableTreeNode finNodes = (DefaultMutableTreeNode)
          root.getChildAfter(curNodes);
      DefaultMutableTreeNode delNodes = (DefaultMutableTreeNode)
          root.getChildAfter(finNodes);
      enu = curNodes.children();
      while (enu.hasMoreElements())
      {
        node = (DefaultMutableTreeNode)enu.nextElement();
        if (node.getUserObject() instanceof TaskDescription)
        {
          description = (TaskDescription)node.getUserObject();
          DefaultTableModel dtm = (DefaultTableModel)taskTable.getModel();
          Vector v = dtm.getDataVector();
          int size = v.size();
          for (int i=0;i<size;i++)
          {
            task = null;
            if (v.get(i) instanceof Task)
             {
               task = (Task) v.get(i);
               if (task.getTaskDescription()==description)
                 break;
             }
          }
          if (task==null)
            return;
          process = task.getTaskProcess(0);
          if (process.getLength()==0)
            continue;
          if (process.getLength()==process.getFinished())
          {
            curNodes.remove(node);
            finNodes.add(node);
            model.nodeStructureChanged(curNodes);
            model.nodeStructureChanged(finNodes);
          }
        }
      }
      saveTaskTree();
    }
  }

  DefaultTreeModel getTaskTreeModel()
  {
   return starfire.gui.siteTree.TreeXmlSupport.getTaskTreeModel();
  }

  public void saveTaskTree()
  {
    starfire.gui.siteTree.TreeXmlSupport.saveTaskTreeModel(
       (DefaultTreeModel)taskTree.getModel());
  }

  public void addTask(Task task)
  {
    DefaultTreeModel model = (DefaultTreeModel)taskTree.getModel();
    DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)root.getFirstChild();
    DefaultMutableTreeNode urlNode = new DefaultMutableTreeNode(
        task.getTaskDescription(),false);
    urlNode.setUserObject(task.getTaskDescription());
    node.add(urlNode);
    model.nodeStructureChanged(node);
    TaskTableModel ttm = (TaskTableModel)taskTable.getModel();
    ttm.addTask(task);
    taskTable.updateUI();
    taskTree.updateUI();
    saveTaskTree();
  }

   protected void finalize ()
  {
    saveTaskTree();
  }

  class TaskTableModel extends DefaultTableModel
  {


    public String getColumnName(int column) {
      if (column<strColumnInfo.length)
        return (String)strColumnInfo[column];
      return null;
    }

    public Class getColumnClass(int columnIndex) {
      return String.class;
    }

    public boolean isCellEditable(int rowIndex, int columnIndex) {
      return false;
    }

    public void setValueAt(Object aValue, int row, int column) {
      if (column!=0)
        return;
      if (aValue instanceof Task)
      {
        dataVector.set(row,aValue);
      }
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
      Object o = dataVector.get(rowIndex);
      if (o==null)
        return null;
      Task task = (Task)o;
      TaskDescription description = task.getTaskDescription();
      TaskProcess process = task.getTaskProcess(0);
      switch (columnIndex)
      {
        case statusColumn :
          return task.getState()==Task.TASKSTARTING?"started":"stopped";
        case resumeColumn :
          return "false";
        case nameColumn :
          String path = description.getTaskURL().getFile();
          int index = path.lastIndexOf("/");
          if (index==path.length())
            index = -1;
          return path.substring(index+1);
        case lengthColumn :
          return String.valueOf(process.getLength());
        case finishedLengthColumn :
          return String.valueOf(process.getFinished());
        case  percentColumn :
          return
              process.getLength()==0?"0"
              :((int)((process.getFinished()*1.0f)/process.getLength()*100)+"%");
        case usedTimeColumn :
          return "";
        case leftTimeColumn :
          return "";
        case currentSpeedColumn :
          return String.valueOf(process.getCurrentSpeed());
        case maxSpeedColumn :
          return String.valueOf(process.getMaxSpeed());
        case blockNumColumn :
          return String.valueOf(task.getThreadNum());
        case retryNumColumn :
          return "0";
        case urlColumn :
          return description.getTaskURL().toString();
        case commentColumn :
          return description.getComment();
      }
      return "";
    }

    public int getColumnCount() {
      return columnCount;
    }

    public void addTask(Task task)
    {
      dataVector.add(task);
      setNumRows(dataVector.size());
    }

    public Task getTask(int index) {
      return (Task)dataVector.get(index);
    }

    public void removeTask(Task task) {
      dataVector.remove(task);
    }

  }

  void onTableClicked(MouseEvent e) {
    if (SwingUtilities.isRightMouseButton(e))
    {
      DefaultTableModel model = (DefaultTableModel)taskTable.getModel();
      if (taskTable.getSelectedRow()<0)
        return;
      Task task = (Task)(model.getDataVector().get(taskTable.getSelectedRow()));
      int state = task.getState();
      startItem.setEnabled(true);
      pauseItem.setEnabled(true);
      restartItem.setEnabled(true);
      stopItem.setEnabled(true);
      deleteItem.setEnabled(true);
      if (state==Task.TASKRUNNING)
      {
        startItem.setEnabled(false);
      }
      else
      {
        stopItem.setEnabled(false);
        pauseItem.setEnabled(false);
        restartItem.setEnabled(false);
      }
      taskTableMenu.show(taskTable,e.getX(),e.getY());
    }
  }

  Task getSelectedTask() {
    int selected = taskTable.getSelectedRow();
    if (selected < 0) {
      return null;
    }
   TaskTableModel model = (TaskTableModel)taskTable.getModel();
    Task task = model.getTask(selected);
    return task;
  }

  void onStop(ActionEvent e) {
    Task task = getSelectedTask();
    if (task==null)
      return;
    try {
      task.stop(0);
    }
    catch (TaskException ex) {
      ex.printStackTrace();
    }
  }

  void onPause(ActionEvent e) {
    Task task = getSelectedTask();
    if (task==null || task.getState()!=Task.TASKRUNNING)
      return;
    try {
      task.pause(0);
    }
    catch (TaskException ex) {
      ex.printStackTrace();
    }

  }

  void onRestart(ActionEvent e) {
    Task task = getSelectedTask();
    if (task==null || task.getState()==Task.TASKRUNNING)
      return;
    try {
      task.restart(0);
    }
    catch (TaskException ex) {
      ex.printStackTrace();
    }

  }

  void onDelete(ActionEvent e) {
    Task task = getSelectedTask();
    if (task==null)
      return;
    if (task.getState() == Task.TASKRUNNING) {
      task.stopAll();
    }
    TaskTableModel model = (TaskTableModel) taskTable.getModel();
    model.removeTask(task);
  }

}

class DownloadManagerPanel_taskTable_mouseAdapter extends java.awt.event.MouseAdapter {
  DownloadManagerPanel adaptee;

  DownloadManagerPanel_taskTable_mouseAdapter(DownloadManagerPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void mouseClicked(MouseEvent e) {
    adaptee.onTableClicked(e);
  }
}

class DownloadManagerPanel_stopItem_actionAdapter implements java.awt.event.ActionListener {
  DownloadManagerPanel adaptee;

  DownloadManagerPanel_stopItem_actionAdapter(DownloadManagerPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onStop(e);
  }
}

class DownloadManagerPanel_pauseItem_actionAdapter implements java.awt.event.ActionListener {
  DownloadManagerPanel adaptee;

  DownloadManagerPanel_pauseItem_actionAdapter(DownloadManagerPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onPause(e);
  }
}

class DownloadManagerPanel_restartItem_actionAdapter implements java.awt.event.ActionListener {
  DownloadManagerPanel adaptee;

  DownloadManagerPanel_restartItem_actionAdapter(DownloadManagerPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onRestart(e);
  }
}

class DownloadManagerPanel_deleteItem_actionAdapter implements java.awt.event.ActionListener {
  DownloadManagerPanel adaptee;

  DownloadManagerPanel_deleteItem_actionAdapter(DownloadManagerPanel adaptee) {
    this.adaptee = adaptee;
  }
  public void actionPerformed(ActionEvent e) {
    adaptee.onDelete(e);
  }
}

